--- @param extension Package
--- @param HY HY_Utility
--- @param U Utility
return function(extension, HY, U)
    local hy_x_hakurei_reimu = General:new(extension, "hy_x_hakurei_reimu", "x_k", 3, 3, General.Female)
    local create_isolation = fk.CreateSkill {
        name = "create_isolation",
    }
    create_isolation:addEffect(fk.GameStart, {
        anim_type = "switch",
        can_trigger = function(self, event, target, player, data)
            return player:hasSkill(self)
        end,
        on_cost = Util.TrueFunc,
        on_use = function(self, event, target, player, data)
            local room = player.room
            local targets = {}
            local max = math.floor(#room.players / 2)
            for i = 1, max, 1 do
                local temp = table.except(room:getAllPlayers(), targets)
                local t = room:askToChoosePlayers(player, {
                    targets = temp,
                    min_num = 1,
                    max_num = 1,
                    prompt = "create_isolation_prompt:::" .. tostring(i),
                    skill_name = create_isolation.name
                })
                if #t == 0 then
                    break
                else
                    table.insertIfNeed(targets, t[1])
                end
            end
            for i = 1, #targets, 1 do
                room:setPlayerMark(targets[i], "@create_isolation", i)
            end
        end,
    })
    create_isolation:addEffect(fk.RoundStart, {
        anim_type = "switch",
        can_trigger = function(self, event, target, player, data)
            return player:hasSkill(self)
        end,
        on_cost = Util.TrueFunc,
        on_use = function(self, event, target, player, data)
            local room = player.room
            local targets = {}
            local max = math.floor(#room.players / 2)
            for i = max, 1, -1 do
                table.insertTableIfNeed(targets, table.filter(room.alive_players, function(t)
                    return t:getMark("@create_isolation") == i
                end))
            end
            for _, t in ipairs(targets) do
                t:gainAnExtraTurn(true, create_isolation.name)
            end
        end,
    })
    create_isolation:addEffect(fk.TurnEnd, {
        anim_type = "switch",
        can_trigger = function(self, event, target, player, data)
            return target:insideExtraTurn() and target:getCurrentExtraTurnReason() == create_isolation.name and target == player and not target.dead
        end,
        on_cost = Util.TrueFunc,
        on_use = function(self, event, target, player, data)
            target:turnOver()
        end,
    })
    create_isolation:addEffect(fk.Death, {
        can_refresh = function(self, event, target, player, data)
            return target == player and player:hasSkill(self, true, true)
        end,
        on_refresh = function(self, event, target, player, data)
            for _, t in ipairs(player.room.players) do
                player.room:setPlayerMark(t, "@create_isolation", 0)
            end
        end
    })
    local maintain_balance = fk.CreateSkill {
        name = "maintain_balance",
    }
    maintain_balance:addEffect(fk.EventPhaseStart, {
        anim_type = "switch",
        can_trigger = function(self, event, target, player, data)
            return player:hasSkill(self) and player ~= target and #player:getCardIds("he") > 0
                and ((target:insideExtraTurn() and target.phase == Player.Start)
                    or (not target:insideExtraTurn() and target.phase == Player.Finish and #target:getCardIds("ej") > 0 and #table.filter(player.room:getOtherPlayers(target), function(
                        t)
                        return table.any(target:getCardIds("ej"), function(id)
                            return target:canMoveCardInBoardTo(t, id)
                        end)
                    end) > 0))
        end,
        on_cost = function(self, event, target, player, data)
            local pattern
            local prompt
            if target:insideExtraTurn() then
                pattern = ".|.|.|.|.|basic,equip"
                prompt = "maintain_balance_prompt_extra::" .. target.id
            else
                pattern = ".|.|.|.|.|trick,equip"
                prompt = "maintain_balance_prompt_normal::" .. target.id
            end
            local cards = player.room:askToCards(player, {
                min_num = 1,
                max_num = 1,
                include_equip = true,
                skill_name = maintain_balance.name,
                pattern = pattern,
                prompt = prompt
            })
            if type(cards) == "number" then
                cards = { cards }
            end
            event:setCostData(self, cards)
            return #cards > 0
        end,
        on_use = function(self, event, target, player, data)
            local room = player.room
            local card = Fk:getCardById(event:getCostData(self)[1])
            room:moveCardTo(card, Card.PlayerHand, target, fk.ReasonGive, maintain_balance.name, nil, false, player)
            if target:insideExtraTurn() then
                room:drawCards(player, 1, maintain_balance.name)
            else
                local targets = table.filter(player.room:getOtherPlayers(target), function(t)
                    return table.any(target:getCardIds("ej"), function(id)
                        return target:canMoveCardInBoardTo(t, id)
                    end)
                end)
                local moveTarget = room:askToChoosePlayers(player, {
                    targets = targets,
                    min_num = 1,
                    max_num = 1,
                    prompt = "maintain_balance_prompt_move::" .. target.id,
                    skill_name = maintain_balance.name,
                    cancelable = false,
                })
                if #moveTarget > 0 then
                    local target2 = moveTarget[1]
                    room:askToMoveCardInBoard(player, {
                        target_one = target,
                        target_two = target2,
                        skill_name = maintain_balance.name,
                        move_from = target
                    })
                end
            end
        end
    })
    extension:loadSkillSkels { create_isolation, maintain_balance }
    hy_x_hakurei_reimu:addSkill("create_isolation")
    hy_x_hakurei_reimu:addSkill("maintain_balance")
    Fk:loadTranslationTable {
        ["hy_x_hakurei_reimu"] = "博丽灵梦",
        ["#hy_x_hakurei_reimu"] = "异界的此端",
        ["illustrator:hy_x_hakurei_reimu"] = "L.F.",
        ["designer:hy_x_hakurei_reimu"] = "黑曜人形",
        ["cv:hy_x_hakurei_reimu"] = "",

        ["create_isolation"] = "封隔",
        [":create_isolation"] = "游戏开始时，你选择至多一半（向下取整）的角色。每轮开始时，这些角色按你选择的次序依次执行一个额外回合。以此法执行的额外回合结束时，对应的角色翻面。",
        ["@create_isolation"] = "封隔",
        ["create_isolation_prompt"] = "封隔：选择第%arg名角色",

        ["maintain_balance"] = "定衡",
        [":maintain_balance"] = "其他角色的非额外回合的结束阶段，你可以交给其一张非基本牌并移动其场上一张牌。其他角色的额外回合的准备阶段，你可以交给其一张非锦囊牌并摸一张牌。",
        ["maintain_balance_prompt_extra"] = "定衡：你可以交给%dest一张非锦囊牌并摸一张牌",
        ["maintain_balance_prompt_normal"] = "定衡：你可以交给%dest一张非基本牌并移动其场上一张牌",
        ["maintain_balance_prompt_move"] = "定衡：你须移动%dest场上一张牌",
    }
end
